-- uu.lua
local uuhdr=Proto.new("uuhdr", "interface uu header")

local channeltype_list = 
{
    [0x00] = "BCCH-BCH-Message",
    [0x01] = "BCCH-DL-SCH-Message",
    [0x02] = "MCCH-Message",
    [0x03] = "PCCH-Message",
    [0x04] = "DL-CCCH-Message",
    [0x05] = "DL-DCCH-Message",
    [0x06] = "UL-CCCH-Message",
    [0x07] = "DL-DCCH-Message",
}

local uuhdr_len = ProtoField.uint8("uuhdr.len", "len", base.DEC)
local uuhdr_enbid = ProtoField.uint32("uuhdr.enodeb_id", "enodeb_id", base.DEC)
local uuhdr_sectorid = ProtoField.uint16("uuhdr.sectorid", "sectorid", base.DEC)
local uuhdr_channeltype= ProtoField.uint8("uuhdr.channel_type", "channel_type", base.DEC, channeltype_list)
local uuhdr_crnti= ProtoField.uint16("uuhdr.c-rnti", "c-rnti", base.DEC)
local uuhdr_mmeueid= ProtoField.uint32("uuhdr.mme_ue_s1ap_id", "mme_ue_s1ap_id", base.DEC)
local uuhdr_mmegid= ProtoField.uint16("uuhdr.mme_groupid", "mme_groupid", base.DEC)
local uuhdr_mmecode= ProtoField.uint8("uuhdr.mme_code", "mme_code", base.DEC)
local uuhdr_reverse = ProtoField.string("uuhdr.reverse", "reverse")
local uuhdr_data = ProtoField.string("uuhdr.uuhdr_data", "uuhdr_data")

uuhdr.fields = {uuhdr_len, uuhdr_enbid,
    uuhdr_sectorid, uuhdr_channeltype, uuhdr_crnti, uuhdr_mmeueid,
    uuhdr_mmegid, uuhdr_mmecode, uuhdr_reverse, uuhdr_data}

function uuhdr.dissector(buf, pinfo, tree)
    local total_len = buf:len()
    local offset = 0
    -- 取得专用头长度
    local len = buf(offset, 1):uint()
    -- 建立uuhdrtree
    uuhdrtree = tree:add(uuhdr, buf(offset, len + 1), "uuhdr tree")

    -- hdrlen
    uuhdrtree:add(uuhdr_len, buf(offset, 1))

    offset = offset + 1
    local left = len 

    -- enodeb id
    uuhdrtree:add(uuhdr_enbid, buf(offset, 4))
    offset = offset + 4
    left = left - 4

    -- sector id
    uuhdrtree:add(uuhdr_sectorid, buf(offset, 2))
    offset = offset + 2
    left = left - 2

    -- channel type 
    local ch_type = buf(offset, 1):uint()
    uuhdrtree:add(uuhdr_channeltype, buf(offset, 1))
    offset = offset + 1
    left = left - 1

    -- crnti 
    uuhdrtree:add(uuhdr_crnti, buf(offset, 2))
    offset = offset + 2
    left = left - 2

    -- mme_ue_s1ap_id
    uuhdrtree:add(uuhdr_mmeueid, buf(offset, 4))
    offset = offset + 4
    left = left - 4

    ---- mmegid 
    uuhdrtree:add(uuhdr_mmegid, buf(offset, 2))
    offset = offset + 2
    left = left - 2

    -- mmecode
    uuhdrtree:add(uuhdr_mmecode, buf(offset, 1))
    offset = offset + 1
    left = left - 1

    -- reverse
    uuhdrtree:add(uuhdr_reverse, buf(offset, left), left.." bytes")
    offset = offset + left

    local dlen = total_len - offset
    if (dlen > 0) then
        --uuhdrtree:add(uuhdr_data, buf(offset, dlen), dlen.." bytes")
        --local diss = Dissector.get("rrc") 
        --Dissector.call(diss, buf(offset, dlen):tvb(), pinfo, uuhdrtree)
        local diss = None
        if ch_type == 0x00 then
            diss = Dissector.get("lte_rrc.bcch_bch")
        elseif ch_type == 0x01 then
            diss = Dissector.get("lte_rrc.bcch_dl_sch")
        elseif ch_type == 0x02 then
            diss = Dissector.get("lte_rrc.mcch")
        elseif ch_type == 0x03 then
            diss = Dissector.get("lte_rrc.pcch")
        elseif ch_type == 0x04 then
            diss = Dissector.get("lte_rrc.dl_ccch")
        elseif ch_type == 0x05 then
            diss = Dissector.get("lte_rrc.dl_dcch")
        elseif ch_type == 0x06 then
            diss = Dissector.get("lte_rrc.ul_ccch")
        elseif ch_type == 0x07 then
            diss = Dissector.get("lte_rrc.ul_dcch")
        end
        Dissector.call(diss, buf(offset, dlen):tvb(), pinfo, uuhdrtree)
    end
end
